home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 July: Mac OS SDK / Dev.CD Jul 00 SDK2.toast / Development Kits / Hardware / Mac OS USB DDK / Mac OS USB DDK 1.4.1 / Examples / PrinterClassDriver / usbprint.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-04-25  |  8.2 KB  |  387 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        usbprint.c
  3.  
  4.     Contains:    usb printer class device communication
  5.                     (installed in UnitTable)
  6.  
  7.     Version:    xxx put version here xxx
  8.  
  9.  
  10.  
  11.     Copyright: 1998 by Apple Computer, Inc., all rights reserved.
  12.  
  13. */
  14. #include "PrinterClassDriver.h"
  15.  
  16. #ifndef __DEVICES__
  17. #include <devices.h>
  18. #endif
  19.  
  20. #ifndef __FILES__
  21. #include <files.h>
  22. #endif
  23.  
  24. #define kMaskLowByte    0x0FF
  25.  
  26. static void AbortActive( CntrlParam *pb, DCtlPtr clt );
  27.  
  28. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  29.     Name:        GetPrinterStruct
  30.  
  31.     Input Parameters:    IOParamPtr        i/o parameter block
  32.         
  33.     Output Parameters:
  34.         usbPrinterPBStruct    * pointer to the device
  35.         
  36.     Description:
  37.         Given a device control block, map it to a usb device's data structure
  38.  
  39.  
  40.  
  41. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  42. static struct usbPrinterPBStruct    *
  43. GetPrinterStruct( DCtlPtr ctl )
  44. {
  45.     return (struct usbPrinterPBStruct *) ctl->dCtlStorage;
  46. }
  47.  
  48. // BT - 15Jun99, send a control call to the class driver asking it to put message in log.
  49. static OSStatus usbPrintLogStatus(CntrlParam *pb, DCtlPtr ctl, UInt32 level, unsigned char *s, UInt32 param)
  50. {
  51. struct             usbPrinterPBStruct    *usbprint = GetPrinterStruct( ctl );
  52.     pb->csCode = kDrvrPrivateLog;
  53.     *(unsigned char **)pb->csParam = s;
  54.     *(UInt32 *)&pb->csParam[4] = param;
  55.     pb->csParam[2] = level;
  56.     if ( usbprint && usbprint->qstatus )
  57.         return (*usbprint->qstatus)( pb, ctl, usbprint );    //    map the status param block into the usb param block
  58.     return(-1);
  59. }
  60.  
  61. // BT - 15Jun99, send a control call to the PPC driver.
  62. static OSStatus usbPrintSendCntl(CntrlParam *pb, DCtlPtr ctl, UInt32 csCode, UInt32 param)
  63. {
  64. struct             usbPrinterPBStruct    *usbprint = GetPrinterStruct( ctl );
  65.     pb->csCode = csCode;
  66.     pb->csParam[0] = param;
  67.     if ( usbprint && usbprint->qstatus )
  68.         return (*usbprint->qstatus)( pb, ctl, usbprint );    //    map the status param block into the usb param block
  69.     return(-1);
  70. }
  71.  
  72.  
  73. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  74.     Name:        Read
  75.  
  76.     Input Parameters:
  77.         
  78.     Output Parameters:
  79.         <none>
  80.         
  81.     Description:
  82.         
  83.  
  84.  
  85.  
  86.  
  87. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  88. static OSErr
  89. Read (IOParamPtr pb, DCtlPtr ctl)
  90. {
  91.     struct usbPrinterPBStruct    *usbprint = GetPrinterStruct( ctl );
  92.  
  93.     //
  94.     //    if we have a unidirectional interface
  95.     //        report a read error
  96.     //        (only status supported by unidirectional is Centronics compatible)
  97.     //
  98.     pb->ioResult = paramErr;    // assume bad
  99.  
  100.     if ( usbprint != nil )
  101.     {
  102.         if ( usbprint->printerProtocol == kUSBPrinterUnidirectionalProtocol )
  103.             pb->ioResult = readErr;
  104.             
  105.         else if (usbprint->terminating)
  106.             pb->ioResult = abortErr;    
  107.             
  108.         else if (usbprint->qread)
  109.             (*usbprint->qread)( pb, ctl, usbprint );    //    map the read param block into the usb param block
  110.     }
  111.     return pb->ioResult;
  112.  
  113. }
  114.  
  115. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  116.     Name:        Write
  117.  
  118.     Input Parameters:
  119.         
  120.     Output Parameters:
  121.         <none>
  122.         
  123.     Description:
  124.         
  125.  
  126.  
  127.  
  128.  
  129. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  130. static OSErr
  131. Write (IOParamPtr pb, DCtlPtr ctl)
  132. {
  133.     struct usbPrinterPBStruct    *usbprint = GetPrinterStruct( ctl );
  134.  
  135.     pb->ioResult = paramErr;    // assume bad
  136.  
  137.     if ( usbprint != nil )
  138.     {
  139.         if (usbprint->terminating)
  140.             pb->ioResult = abortErr;
  141.             
  142.         else if (usbprint->qwrite)
  143.             (*usbprint->qwrite)( pb, ctl, usbprint );    //    map the write param block into the usb param block
  144.     }
  145.     return pb->ioResult;
  146. }
  147.  
  148. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  149.     Name:        AbortActive
  150.  
  151.     Input Parameters:
  152.         pb
  153.         ctl
  154.         
  155.     Output Parameters:
  156.         <none>
  157.         
  158.     Description:
  159.         
  160.  
  161.  
  162. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  163. static void
  164. AbortActive( CntrlParam *pb, DCtlPtr ctl )
  165. {
  166.     //        we need to wait here until the transaction is complete
  167.     struct usbPrinterPBStruct    *usbprint = GetPrinterStruct( ctl );
  168.     struct USBPB                    *pActiveUSBIO;
  169.     IOParamPtr                        pActiveIO;
  170.  
  171.     if ( usbprint != nil )
  172.     {
  173.         if ( pb->ioCRefNum == usbprint->outRefNum )
  174.         {
  175.             pActiveUSBIO = &usbprint->out;
  176.             pActiveIO = usbprint->writeDrvr.pb;
  177.         }
  178.         else
  179.         {
  180.             pActiveUSBIO = &usbprint->in;
  181.             pActiveIO = usbprint->readDrvr.pb;
  182.         }
  183.         
  184.         if ( pActiveUSBIO->usbCompletion != nil )
  185.         {
  186.             if (usbprint->qabort != nil )
  187.                 (*usbprint->qabort)( pb->ioCRefNum, usbprint );    //    cancel outstanding transactions
  188.             //
  189.             //    synchronize data toggle
  190.             // USB addendum, the endpoints of the pipe may be out of sync
  191.             //    a soft reset in the printer class should restore the data toggle
  192.             //
  193.             if (!(usbprint->terminating) && (usbprint->qstatus != nil))
  194.             {
  195.                 pb->csCode = kDrvrSoftReset;
  196.                 (*usbprint->qstatus)( pb, ctl, usbprint );
  197.             }
  198.         }
  199.     }
  200. }
  201.  
  202. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  203.     Name:        DRVROpen
  204.  
  205.     Input Parameters:
  206.         
  207.     Output Parameters:
  208.         <none>
  209.         
  210.     Description:
  211.         
  212.  
  213.  
  214. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  215.  
  216. OSErr
  217. DRVROpen(CntrlParam *pb, DCtlPtr dce)
  218. {
  219. //#pragma unused (pb)
  220. #pragma unused (dce)
  221.  
  222.     usbPrintLogStatus(pb, dce, 5, "\pUSB Print driver being opened", 3);
  223.     usbPrintSendCntl(pb, dce, kDrvrPrivateOpnClose, 1);
  224.     return noErr;
  225. }
  226.  
  227. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  228.     Name:        DRVRClose
  229.  
  230.     Input Parameters:
  231.         
  232.     Output Parameters:
  233.         <none>
  234.         
  235.     Description:
  236.         
  237.  
  238.  
  239. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  240.  
  241. OSErr
  242. DRVRClose(CntrlParam *pb, DCtlPtr ctl)
  243. {
  244. //#pragma unused (pb)
  245. #pragma unused (ctl)
  246.  
  247.     usbPrintLogStatus(pb, ctl, 5, "\pUSB Print driver being closed", 2);
  248.     usbPrintSendCntl(pb, ctl, kDrvrPrivateOpnClose, 0);
  249.     return noErr;
  250. }
  251.  
  252. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  253.     Name:        DRVRStatus
  254.  
  255.     Input Parameters:
  256.         
  257.     Output Parameters:
  258.         <none>
  259.         
  260.     Description:
  261.         
  262.  
  263.  
  264.  
  265.  
  266. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  267.  
  268. OSErr
  269. DRVRStatus(CntrlParam *pb, DCtlPtr ctl)
  270. {
  271. struct             usbPrinterPBStruct    *usbprint = GetPrinterStruct( ctl );
  272.  
  273.     pb->ioResult = paramErr;
  274.     if ( usbprint != nil )
  275.     {
  276.         if (usbprint->terminating)
  277.             pb->ioResult = abortErr;    
  278.         else
  279.         {
  280.             switch ( pb->csCode )
  281.             {
  282.                 case kDrvrCentronicsStatus:        //  USB device: centronics status
  283.                 case kDrvr1284IdString:             //  USB device: 1284 capability string
  284.                 case kDrvrSoftReset:                    //  USB device: soft reset
  285.                     if ( usbprint->qstatus )
  286.                         (*usbprint->qstatus)( pb, ctl, usbprint );    //    map the status param block into the usb param block
  287.                     break;
  288.                 case kDrvrNumDevices:    
  289.                     pb->ioResult =  noErr;
  290.                     break;
  291.                 case 1:    
  292.                 case 2:                                    // deprecated
  293.                 default:
  294.                     pb->ioResult = paramErr;
  295.                     break;
  296.             }
  297.         }
  298.     }
  299.     return pb->ioResult;
  300. }
  301.  
  302. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  303.     Name:        DRVRControl
  304.  
  305.     Input Parameters:
  306.         csCode                        csParam
  307.         ------                        -------
  308.         kDrvrPrivateSetStorage    pointer to the USB device class storage
  309.  
  310.     Output Parameters:
  311.         <none>
  312.         
  313.     Description:
  314.         
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  322.  
  323. OSErr
  324. DRVRControl(CntrlParam *pb, DCtlPtr ctl)
  325. {
  326.     OSErr                                err            = noErr;
  327.  
  328.     switch ( pb->csCode )
  329.     {
  330.     case killCode:
  331.         //
  332.         //    killIO is always handled as an immediate mode transaction
  333.         //
  334.         AbortActive( pb, ctl );
  335.         break;
  336.     case kDrvrPrivateSetStorage:
  337.         //
  338.         //    reference the class driver's private storage
  339.         //        it's not a handle, but devices.h thinks it should be
  340.         //
  341.         ctl->dCtlStorage = (Handle) *((Ptr *) &pb->csParam[0] );
  342.         break;
  343.     default:
  344.         err = paramErr;
  345.         break;
  346.     }
  347.     return err;
  348. }
  349.  
  350. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  351.     Name:        DRVRPrime
  352.  
  353.     Input Parameters:
  354.         
  355.     Output Parameters:
  356.         <none>
  357.         
  358.     Description:
  359.         
  360.  
  361.  
  362. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  363.  
  364. OSErr
  365. DRVRPrime(CntrlParam *pb, DCtlPtr ctl)
  366. {
  367.     OSErr    err = paramErr;
  368.     //
  369.     //    switch on the low order byte to dispatch reads and writes
  370.     //
  371.     if ( (pb->ioTrap & kMaskLowByte) == aRdCmd )
  372.         err = Read( (IOParamPtr) pb, ctl );
  373.         
  374.     else if ( (pb->ioTrap & kMaskLowByte) == aWrCmd )
  375.         err = Write( (IOParamPtr) pb, ctl );
  376.  
  377.     //
  378.     //    get the ioResult in case the completion routine has already executed
  379.     //    
  380.     if ( err == noErr )
  381.         err = pb->ioResult;
  382.  
  383.     return err;
  384. }
  385.  
  386. // eof
  387.